<template>
  <demo-content :title="title">
    <p>
      除了颜色与渐变色外，Canvas
      元素也允许使用图案来对图形和文本就行描边与填充。这里的图案可以是以下三种之一：image
      元素、canvas 元素或 video 元素。
    </p>
    <p>
      可以用 createPattern()方法来创建图案，该方法接收两个参数：图案本身以及一个
      用来告知浏览器应该如何重复图案的字符串。
      第二个参数可以取如下的值：repeat、 repeat-x、repeat-y或者no-repeat。
    </p>
    <p>
      注意：每次用户点击多选按钮时，应用程序的代码都会调用 createPattern
      方法来创建一个新的 CanvasPattern 对象，因为 CanvasPattern 是 JS
      中的所谓不透明对象(opaque
      object)，它没有提供用于操作其内容的属性及方法。如果 CanvasPattern
      对象提供了 setPattern 的方法，那可以只建立一个 CanvasPattern
      对象，但事实是没有这样的函数。
    </p>
    <div>
      repetition:
      <template v-for="v of [null, 'repeat', 'repeat-x', 'repeat-y']">
        <label>
          <input
            type="radio"
            name="repetition"
            :value="v"
            v-model="repetition"
          />
          <span style="margin-right: 7px">{{ v ? v : "null" }}</span>
        </label>
      </template>
    </div>
    <canvas width="600" height="400" ref="canvasRef"></canvas>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import _ from "lodash";
import { rect, type PatternRepetition } from "./utils";
import imagePath from "@/assets/redball.png";
import { watchEffect } from "vue";

const title = "图案";
// 指定组件上的属性
defineOptions({ title });
const repetition = ref<PatternRepetition>(null);
const canvasRef = ref<HTMLCanvasElement>();

const image = new Image();
let canvas: HTMLCanvasElement;

function changePattern(ctx: CanvasRenderingContext2D) {
  const pattern = ctx.createPattern(image, repetition.value)!;
  const drawArea = {
    x: 0,
    y: 0,
    w: canvas.width,
    h: canvas.height,
  };
  rect.clear(ctx, drawArea);
  rect.draw(ctx, { ...drawArea, fillStyle: pattern });
}

onMounted(() => {
  canvas = canvasRef.value!;
  const ctx = canvas.getContext("2d")!;
  image.onload = () => {
    changePattern(ctx);
  };
  image.src = imagePath;
  watchEffect(() => {
    changePattern(ctx);
  });
  // watch(repetition, (nv) => changePattern(ctx));
});
</script>

<style src="./default.css" scoped></style>
